
這次的內容是,當我們在搜索欄打字母,會篩選出相應的城市名稱,達到搜尋篩選的效果
實做連結
const suggestions = document.querySelector(".suggestions");
  const search = document.querySelector(".search");
  // 當鍵盤keyup時
  search.addEventListener("keyup", displayMatches);
  search.addEventListener("change", displayMatches);
我們在監聽的時候主要是監聽keyup 以及change 事件
keyupkeyup 事件都會觸發。所以我們要額外增加監聽事件change ,change能捕捉到通過剪貼板粘貼文本、使用語音輸入、更改選項列表中的值等方式進行的輸入變化,正好可以補齊keyup的缺失。
  let cities = [];
  //取得城市的資料
  const endpoint = fetch(
    "https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json"
  );
  endpoint
    .then((res) => res.json())
    .then((data) => {
      cities.push(...data);
    });
我們要透過json文件去抓取我們的資料,要取得endpoint的資料需要利用json() 去讀取並解析數據,當取得後數據會傳遞給下一個 then 方法。 data 是一個包含所有城市和州信息的數組。cities.push(...data) 使用展開運算符(...)將 data 數組中的所有元素逐個插入到 cities 數組中。
當我們去console.log(cities)時可以看到陣列裡包裹著許多物件資料,把[0]物件展開來看會出現以下的內容:
{city: "New York"
growth_from_2000_to_2013: "4.8%"
latitude: 40.7127837
longitude: -74.0059413
population: "8405837"
rank: "1"
state: "New York"}
 function findMatches(wordToMatch, cities) {
    return cities.filter((place) => {
      const regex = new RegExp(wordToMatch, "gi");
      return place.city.match(regex) || place.state.match(regex);
    });
  }
使用 filter()來篩選符合條件的城市
創建一個正則表達式,參數為 wordToMatch,gi 表示全局搜索且忽略大小寫,
使用 match()來檢查cities每個子元素的屬性city 或 state其一是否與正則表達式匹配
  function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }
這段是用來處理,cities中的population屬性,我們利用正則表達式將一個數字格式化,在數字串中的每個千位位置添加逗點","符號,使字串從1234567轉為1,234,567
 function displayMatches() {
    const matchArray = findMatches(this.value, cities);
    
    const html = matchArray
      .map((place) => {
        // 將城市名和州名中與搜索關鍵字匹配的部分用 <span class="hl"> 包裹起來做出提亮效果
        const regex = new RegExp(this.value, "gi");
        const cityName = place.city.replace(
          regex,
          `<span class="hl">${this.value}</span>`
        );
        const stateName = place.state.replace(
          regex,
          `<span class="hl">${this.value}</span>`
        );
        return `
            <li>
              <span class="name">${cityName}, ${stateName}</span>
              <span class="population">${numberWithCommas(
                place.population //取被篩選過後cities的.population元素
              )}</span>
            </li>
          `;
      })
      .join("");
    suggestions.innerHTML = html;
  }
matchArray 內的findMatches(this.value)為當我們在搜索欄打字時取得的值,帶入函式內便可以比對我們輸入的值 以及cities 是否有對應的城市或州,並且篩選為一個陣列
place.city.replace 找到與place.city對應的regex詞彙並轉換成<span class="hl">${this.value}</span>做出字體提亮效果
suggestions.innerHTML=html 將我們取得的資料顯示在網頁上
obj.replace(a,b) replace可以用來尋找arr中與a相應的字串並替換成的內容Fetch API: 使用 fetch() 從遠程服務器請求數據。fetch() 返回一個 Promise,可以通過 .then() 方法鏈式調用來處理響應數據。正則表達式 (RegExp): 正則表達式被用來進行字符串匹配。在此內容,input輸入的字串被轉換為一個正則表達式,用來篩選城市或州名中是否包含這個搜索詞。 new RegExp(wordToMatch, "gi") 中的 "gi" 表示全局匹配並忽略大小寫。JS30
[ Alex 宅幹嘛 ] 👨💻 深入淺出 Javascript30 快速導覽:Day 6:Type Ahead